/*  
* Copyright (c) 2010, James Daniello
* This project is licensed under the 'New BSD' license.
* The full text of the license can be found in the root
* directory under the filename "LICENSE"
*/
package src.gui;

import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JScrollBar;
import javax.swing.JComponent;
import javax.swing.JList;
import java.awt.Color;
import javax.swing.BorderFactory;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.KeyStroke;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class PICAIUClientGUILobby implements PICAIUGUI{

  //The various gui components.
  private Container frame;       //<-- the main panel container
  private JPanel westPanel;               //<-- west area of panel
  private JPanel eastPanel;               //<-- west area of panel
  private JTextArea lobbyArea;            //<-- the lobby area where the chat text will be displayed
  private JScrollPane lobbyScrollPane;    //<-- the scroll pane for the lobby
  private JTextArea inputArea;            //<-- the input area where the user types in text to other users
  private JScrollPane scrollPaneInput;            //<-- the scroll pane for the area where the user inputs text
  private JList userList;                 //<-- the list of users in lobby
  private JList gamesList;                 //<-- the list of available games
  private JScrollPane userListScrollPane; //<-- the scroll pane for the list of users
  private JScrollPane gamesListScrollPane; //<-- the scroll pane for the list of games

  private PICAIUClientGUI parent;

  //the gui elements for the right hand side (user info and available games)
  private JLabel myInfo;
  private JPanel gamesPadding;
  private JLabel availGames;
  private JPanel gamesAccessPanel;
  private JButton createGame,joinGame;
  private JPanel accessPadding,joinPadding;
  private JTextField joinPass;

  /**
  * Creates the gui component for the lobby screen which can be swapped out on the fly.
  */
  public PICAIUClientGUILobby(Container frameIn, PICAIUClientGUI parentIn){
    frame = frameIn;
    parent = parentIn;
    
    //left hand side with lobby and users
    westPanel = new JPanel();
      lobbyArea = new JTextArea(24,38);
      lobbyScrollPane = new JScrollPane(lobbyArea); 
      lobbyArea.setLineWrap(true);
      lobbyArea.setWrapStyleWord(true);
      lobbyArea.setEditable(false);
      lobbyArea.append("Welcome...");
    
    
    userList = new JList(parent.getUserModel()){
        public String getToolTipText(MouseEvent evt) {
        // Get item index
        int index = userList.locationToIndex(evt.getPoint());

        // Get item
        Object item = userList.getModel().getElementAt(index);

        // Return the tool tip text
        return ""+item;
    }
    };
    userListScrollPane = new JScrollPane(userList);
    userListScrollPane.setMinimumSize(new java.awt.Dimension(107,386));
    userListScrollPane.setPreferredSize(new java.awt.Dimension(107,386));
    userListScrollPane.setMaximumSize(new java.awt.Dimension(107,386));
    userListScrollPane.setSize(new java.awt.Dimension(107,386));
    
    //right hand side with user list
    eastPanel = new JPanel(new FlowLayout());
    eastPanel.setMinimumSize(new java.awt.Dimension(247,286));
    eastPanel.setPreferredSize(new java.awt.Dimension(247,286));
    eastPanel.setMaximumSize(new java.awt.Dimension(247,286));
    eastPanel.setSize(new java.awt.Dimension(247,286));

    //add to east panel
    myInfo = new JLabel("");
    eastPanel.add(myInfo);
    gamesPadding = new JPanel();
    gamesPadding.setMinimumSize(new java.awt.Dimension(247,30));
    gamesPadding.setPreferredSize(new java.awt.Dimension(247,30));
    gamesPadding.setMaximumSize(new java.awt.Dimension(247,30));
    gamesPadding.setSize(new java.awt.Dimension(247,30));
    eastPanel.add(gamesPadding);
    availGames = new JLabel("Available Games:                                                  ");
    eastPanel.add(availGames);
    
    //list of available games
    gamesList = new JList(parent.getGamesModel()){
        public String getToolTipText(MouseEvent evt) {
          if(gamesList.getModel().getSize()<1){
              return "";
          }
          // Get item index
          int index = gamesList.locationToIndex(evt.getPoint());

          // Get item
          Object item = gamesList.getModel().getElementAt(index);

          // Return the tool tip text
          return ""+item;
    }
    };
    gamesList.addListSelectionListener(new ListSelectionListener(){
      public void valueChanged(ListSelectionEvent e) {
        //System.out.println(gamesList.getSelectedIndex());
        if(gamesList.getSelectedIndex()==-1){
          disableJoin();
        }else{
          enableJoin();
        }
      }
    });
    gamesList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

    gamesList.addMouseListener(new MouseListener() {

      public void mouseClicked(MouseEvent e) {
        if (e.getClickCount() == 2 && e.getButton() == 1) {
          parent.getClient().sendDataToServer("JOINGM#"+gamesList.getSelectedValue()+"#"+joinPass.getText());
        }
      }
      public void mousePressed(MouseEvent e) {
      }
      public void mouseReleased(MouseEvent e) {
      }
      public void mouseEntered(MouseEvent e) {
      }
      public void mouseExited(MouseEvent e) {
      }
    });
    gamesListScrollPane = new JScrollPane(gamesList);
    gamesListScrollPane.setMinimumSize(new java.awt.Dimension(245,260));
    gamesListScrollPane.setPreferredSize(new java.awt.Dimension(245,260));
    gamesListScrollPane.setMaximumSize(new java.awt.Dimension(245,260));
    gamesListScrollPane.setSize(new java.awt.Dimension(245,260));
    eastPanel.add(gamesListScrollPane);

    gamesAccessPanel = new JPanel();
    gamesAccessPanel.setMinimumSize(new java.awt.Dimension(245,60));
    gamesAccessPanel.setPreferredSize(new java.awt.Dimension(245,60));
    gamesAccessPanel.setMaximumSize(new java.awt.Dimension(245,60));
    gamesAccessPanel.setSize(new java.awt.Dimension(245,60));
    createGame = new JButton(" Create Game ");
    createGame.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e) {
            parent.setGUI("newgame");
        }
    });
    accessPadding = new JPanel();
    accessPadding.setMinimumSize(new java.awt.Dimension(150,20));
    accessPadding.setPreferredSize(new java.awt.Dimension(150,20));
    accessPadding.setMaximumSize(new java.awt.Dimension(150,20));
    accessPadding.setSize(new java.awt.Dimension(150,20));
    joinGame = new JButton(" Join Game ");
    joinGame.addActionListener(new ActionListener(){
      public void actionPerformed(ActionEvent e) {
        parent.getClient().sendDataToServer("JOINGM#"+gamesList.getSelectedValue()+"#"+joinPass.getText());
      }
    });
    joinPass = new JTextField();
    joinPass.setMinimumSize(new java.awt.Dimension(152,20));
    joinPass.setPreferredSize(new java.awt.Dimension(152,20));
    joinPass.setMaximumSize(new java.awt.Dimension(152,20));
    joinPass.setSize(new java.awt.Dimension(152,20));
    joinPadding = new JPanel();
    joinPadding.setMinimumSize(new java.awt.Dimension(8,20));
    joinPadding.setPreferredSize(new java.awt.Dimension(8,20));
    joinPadding.setMaximumSize(new java.awt.Dimension(8,20));
    joinPadding.setSize(new java.awt.Dimension(8,20));
    gamesAccessPanel.add(createGame);
    gamesAccessPanel.add(accessPadding);
    gamesAccessPanel.add(joinGame);
    gamesAccessPanel.add(joinPadding);
    gamesAccessPanel.add(joinPass);
    eastPanel.add(gamesAccessPanel);


    
    //bottom side with input area
    inputArea = new JTextArea(4,4);
    inputArea.setLineWrap(true);
    inputArea.setWrapStyleWord(true);
    scrollPaneInput = new JScrollPane(inputArea); 
      //add listener for when user presses enter in input area to send text message
      inputArea.registerKeyboardAction(
          new ActionListener() {
            public void actionPerformed(ActionEvent actionEvent) {
              parent.processMessage(inputArea.getText());
              inputArea.setText("");
            }
          },
        KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false)
        ,JComponent.WHEN_FOCUSED
      );
 

    westPanel.add(lobbyScrollPane);
    westPanel.add(userListScrollPane);



    disableJoin();
  }

  
  /**
  * This method switches the clients main container to this GUI's graphics.
  */
  @Override
  public void setAsGUI(){
    
    frame.removeAll();
    //add components to frame
    frame.add(westPanel,BorderLayout.WEST);
    frame.add(eastPanel,BorderLayout.EAST);
    frame.add(scrollPaneInput,BorderLayout.SOUTH);
    //extra stuff
    //make input area first component to receive focus
    inputArea.requestFocusInWindow();
  
    frame.validate();
  }

  /**
  * This sets the colors of all the components affected by the color scheme to that of the current 
  * colors for the GUI
  */
  @Override
  public void setColors(PICAIUGUIScheme colorScheme){
    
    Color colorBG01=colorScheme.getBG01();
    Color colorBG02=colorScheme.getBG02();
    Color colorFG01=colorScheme.getFG01();
    Color colorBorder01=colorScheme.getBorder01();
  
    //panels
    westPanel.setBackground(colorBG01);
    eastPanel.setBackground(colorBG01);
    lobbyArea.setBackground(colorBG02);
    lobbyArea.setForeground(colorFG01);
    userList.setBackground(colorBG02);
    userList.setForeground(colorFG01);
    gamesList.setBackground(colorBG02);
    gamesList.setForeground(colorFG01);
    inputArea.setBackground(colorBG02);
    inputArea.setForeground(colorFG01);

    myInfo.setForeground(colorFG01);
    availGames.setBackground(colorBG01);
    availGames.setForeground(colorFG01);
    gamesPadding.setBackground(colorBG01);
    gamesAccessPanel.setBackground(colorBG01);
    gamesAccessPanel.setForeground(colorFG01);

    createGame.setBackground(colorBG01);
    createGame.setForeground(colorFG01);
    accessPadding.setBackground(colorBG01);
    joinGame.setBackground(colorBG01);
    joinGame.setForeground(colorFG01);
    joinPass.setBackground(colorBG02);
    joinPass.setForeground(colorFG01);
    joinPadding.setBackground(colorBG01);

    if (frame instanceof JFrame){
      ((JFrame)frame).getContentPane().setBackground(colorBG01);
    }else{
      frame.setBackground(colorBG01);
    }
    
    
    //borders
    lobbyScrollPane.setBorder(BorderFactory.createMatteBorder(1,1,1,1, colorBorder01));
    if (frame instanceof JFrame){
      userListScrollPane.setBorder(BorderFactory.createMatteBorder(0,1,0,0, colorBorder01));
    }else{
      userListScrollPane.setBorder(BorderFactory.createMatteBorder(1,1,1,1, colorBorder01));
    }
    gamesAccessPanel.setBorder(BorderFactory.createMatteBorder(0,0,0,0, colorBorder01));
    gamesListScrollPane.setBorder(BorderFactory.createMatteBorder(1,1,1,1, colorBorder01));
    createGame.setBorder(BorderFactory.createMatteBorder(1,1,1,1, colorBorder01));
    joinGame.setBorder(BorderFactory.createMatteBorder(1,1,1,1, colorBorder01));
    joinPass.setBorder(BorderFactory.createMatteBorder(1,1,1,1, colorBorder01));

    if (frame instanceof JFrame){
      scrollPaneInput.setBorder(BorderFactory.createMatteBorder(1,0,0,0, colorBorder01));
    }else{
      scrollPaneInput.setBorder(BorderFactory.createMatteBorder(1,1,1,1, colorBorder01));
    }
    
  }

  /*
   * Disables the join functionality when a game isn't selected
   */
  public void disableJoin(){
      joinGame.setEnabled(false);
      joinPass.setEnabled(false);
      joinGame.setVisible(false);
      joinPass.setVisible(false);
  }
  
  /*
   * enables the join functionality when a game is selected
   */
  public void enableJoin(){
      joinGame.setEnabled(true);
      joinPass.setEnabled(true);
      joinGame.setVisible(true);
      joinPass.setVisible(true);
  }

  /**
  * This method revalidates all componentsd which may have been updated.
  */
  public void validate(){
    userListScrollPane.validate();
  }
  
  
  /**
  * This method takes the string given and displays it to the lobby area. It also
  * accomodates for automatic scrolling. If the user's scroll bar is at the bottom the 
  * window will auto-scroll the new message.
  * @param message the message to be displayed
  */
  protected void writeToLobby(String message){
    lobbyArea.append(System.getProperty("line.separator")+message);
    JScrollBar vbar = lobbyScrollPane.getVerticalScrollBar();
    if ((vbar.getValue() + vbar.getVisibleAmount()) > vbar.getMaximum()-20){
      lobbyArea.setCaretPosition( lobbyArea.getDocument().getLength() ); 
    }
    //this code will flash the application on the task bar. Only verified on windows.
    if (frame instanceof JFrame){
      ((JFrame)frame).toFront();
    }
  }

    void setMyInfo(String string) {
        myInfo.setText("["+string+"]");
    }
}